#ifndef _CAMPIONATO_H_
#define _CAMPIONATO_H_

#include "jogo.h"
#include "equipa.h"
#include <vector>
#include <iostream>

using std::vector;
using std::ostream;
using std::endl;
using std::cout;

//! Classe Equipa_temporada
/*! Serve para associar uma equipa a uma pontuacao num dado campeonato
 */
class Equipa_temporada
{
public:
    //! Construtor
    /*! A pontuacao comeca sempre a 0 */
    Equipa_temporada(Equipa* equipa) : eq(equipa), pontuacao(0) {}

    //! Metodo venceuJogo
    /*! Se a equipa vencer o jogo, adiciona 3 a pontuacao da equipa */
    void venceuJogo() { pontuacao += 3; }
    //! Metodo empatouJogo
    /*! Se a equipa empatou o jogo, adiciona 1 a pontuacao da equipa */
    void empatouJogo() { pontuacao += 1; }
    //! Devolve a pontuacao
    int getPontuacao() { return pontuacao; }
    //! Devolve o nome da equipa
    string getNomeEquipa() { return eq->getNomeEquipa(); }
    //! Devolve o objecto correspondente a Equipa
    Equipa getEquipa() { return *eq; }
    //! Devolve um apontador para o objecto correspondente a Equipa
    Equipa* getEquipa2() { return eq; }

    //! Imprime nome da equipa seguido da pontuacao correspondente
    void imprimir()
    {
        cout << "    " << getNomeEquipa() << endl;
        cout << "Pontuacao: " << getPontuacao();
    }

private:
    //! Variavel privada eq que aponta para uma equipa
    Equipa* eq;
    //! variavel privada pontuacao
    int pontuacao;
};


//! Classe Campeonato
/*! Trata informacao relativa aos campeonatos */
class Campeonato
{
public:
    //! Construtor que recebe apenas o ano
    /*! Year corresponde ao ano do *INICIO* da epoca
      \param year ano
    */
    Campeonato(int year);
    //! Construtor que recebe o ano e  um vector de equipas
    /*!
      \param year ano do campeonato
      \param equipas vector de equipas
    */
    Campeonato(int year, vector<Equipa*> equipas);

    //! Destrutor
    ~Campeonato() {};

    //! Metodo que adiciona uma equipa ao campeonato (indica que esta a participar nele)
    /*!
      \param equipa Apontador para um objecto do tipo Equipa

      \return Devolve true ou lanca excepcao CampeonatoCheio
    */
    bool adicionarEquipa(Equipa* equipa);

    //! Metodo adicionarJogo que adiciona jogos ao campeonato
    /*! Adiciona um jogo que tenha sido jogado entre duas equipas
      TODO: Antes de adicionar o jogo, verificar se os clubes estao a particiar no campeonato.
      \param jogo Apontador para um objecto do tipo Jogo

      \return Devolve true
    */
    bool adicionarJogo(Jogo* jogo);

    //! Metodo que devolve o ano em que o campeonato comecou
    const int getAno();
    //! Metodo que devolve o numero de equipas a participar no campeonato
    int getNumeroEquipas();
    //! Metodo que devolve o numero de jogos ja realizados no campeonato
    int getNumeroJogos();

    //! Metodo que imprime informacoes relativas as equipas no campeonato
    void imprimir();

    //! Metodo que devolve um vector so com as equipas
    vector<Equipa> getEquipas();
    //! Metodo que devolve um vector so com apontadores para as equipas
    vector<Equipa*> getEquipas2();

    //! Metodo que devolve um vector com apontadores para os objectos Jogo que o campeonato tem
    vector<Jogo*> getJogos();

private:
    //! Ano corresponde ao ano do *INICIO* da epoca
    int ano;

    //! Numero maximo de equipas que podem participar no campeonato
    vector<Equipa*>::size_type limite_maximo_de_equipas;
    //! Lista das equipas por temporada
    vector<Equipa_temporada> lista_equipas;
    //! Lista de jogos
    vector<Jogo*> lista_jogos;

    //! Funcao ordenar_equipa
    /* Utiliza-se esta funcao para ordenar as pontuacoes do vector lista_equipas
       Esta funcao e utilizada na funcao sort() definida no ficheiro <algorithm>
       \param eq1 equipa1
       \param eq2 equipa2
    */
    bool ordenar_equipa(Equipa_temporada& eq1, Equipa_temporada& eq2) {
        return eq1.getPontuacao() > eq2.getPontuacao();
    }
};

//! Excepcao Campeonato cheio
/*! Erro usado quando se tenta adicionar uma equipa ao campionato e esta ja tem o maximo
  de equipas que pode ter.
*/
class CampeonatoCheio {
public:
    CampeonatoCheio() {}
};

//! Excepcao LugaresInsuficientes
/*! Erro usado quande se tentar invocar o contructor do Campeonato com um vector que tem
  um tamanho maior do que pode ter.
*/
class LugaresInsuficientes {
public:
    LugaresInsuficientes() {}
};

#endif // _CAMPIONATO_H_
